www.gusucode.com > 基于Visual C++高级界面特效制作百例源码程序 > 基于Visual C++高级界面特效制作百例源码程序/code/char26/appbar/ApBarDlg.cpp
// ApBarDlg.cpp : implementation file // #include "stdafx.h" #include "ApBarDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAppBarDlg dialog CAppBarDlg::CAppBarDlg(int iResource, CWnd* pParent /*=NULL*/) : CDialog(iResource, pParent) { //{{AFX_DATA_INIT(CAppBarDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT m_bMoving = FALSE; m_bHidden = FALSE; m_bOnTop = FALSE; } BEGIN_MESSAGE_MAP(CAppBarDlg, CDialog) //{{AFX_MSG_MAP(CAppBarDlg) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_ACTIVATE() ON_WM_WINDOWPOSCHANGED() ON_WM_SIZE() ON_WM_MOVE() ON_WM_RBUTTONDOWN() ON_WM_TIMER() ON_WM_NCHITTEST() ON_WM_LBUTTONDOWN() ON_WM_MOUSEMOVE() ON_WM_LBUTTONUP() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CAppBarDlg message handlers int CAppBarDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { m_pAppBar = new CAppBar (m_hWnd); ASSERT (m_pAppBar); POPTIONS pOptions; // Initialize the common control DLL InitCommonControls(); // Allocate an OPTIONS struct and attach to the appbar pOptions = (POPTIONS) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OPTIONS)); if (pOptions) { pOptions->fAutoHide = m_bHidden; pOptions->fOnTop = m_bOnTop; pOptions->uSide = ABE_TOP; // Calculate the Height and the width DWORD dwUnits; dwUnits = GetDialogBaseUnits (); pOptions->cyHeight = (CY_DEFHEIGHT*HIWORD (dwUnits)) / 8; pOptions->cxWidth = (CX_DEFWIDTH*LOWORD (dwUnits)) / 4; if (!m_pAppBar->SetAppbarData (pOptions)) { ASSERT (FALSE); } } else { return FALSE; } // Register the appbar and attach it to the top by default m_pAppBar->Register (); m_pAppBar->SetSide (ABE_TOP); return TRUE; } void CAppBarDlg::OnDestroy() { ASSERT (m_pAppBar); if (m_pAppBar) { POPTIONS pOptions = m_pAppBar->GetAppbarData(); // Make sure the appbar is unregistered if (m_pAppBar->IsRegistered ()) { m_pAppBar->UnRegister (); } delete m_pAppBar; m_pAppBar = NULL; } CDialog::OnDestroy (); } void CAppBarDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) { ASSERT (m_pAppBar); CWnd::OnActivate(nState, pWndOther, bMinimized); APPBARDATA abd; // Always send the activate message to the system abd.cbSize = sizeof(APPBARDATA); abd.hWnd = m_hWnd; abd.lParam = 0; SHAppBarMessage(ABM_ACTIVATE, &abd); // Now determine if we're getting or losing activation switch (nState) { case WA_ACTIVE: case WA_CLICKACTIVE: // If we're gaining activation, make sure we're visible m_pAppBar->UnHide(); KillTimer(IDT_AUTOHIDE); break; case WA_INACTIVE: // If we're losing activation, check to see if we need to autohide. m_pAppBar->Hide(); break; } } void CAppBarDlg::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos) { ASSERT (m_pAppBar); CWnd::OnWindowPosChanged(lpwndpos); APPBARDATA abd; abd.cbSize = sizeof(APPBARDATA); abd.hWnd = m_hWnd; abd.lParam = 0; SHAppBarMessage (ABM_WINDOWPOSCHANGED, &abd); CWnd::OnWindowPosChanged(lpwndpos); } void CAppBarDlg::OnSize(UINT nType, int cx, int cy) { ASSERT (m_pAppBar); CString strTemp; CDialog::OnSize(nType, cx, cy); POPTIONS pOpt = m_pAppBar->GetAppbarData(); RECT rcWindow; if (m_bMoving || pOpt->fAutoHide) { return; } // Make sure that client area has dimension if (!pOpt->fHiding && ((cx == 0) || (cy == 0))) { #ifdef LOG strTemp.LoadString (IDS_ZERO_DIMENSION); gLog.WriteError (strTemp); #endif } // Let the system know the appbar size has changed m_pAppBar->Size (); // Update the stored height and widths if the appbar is not hidden if (!pOpt->fHiding) { GetWindowRect(&rcWindow); if (pOpt->uSide == ABE_TOP || pOpt->uSide == ABE_BOTTOM) { pOpt->cyHeight = rcWindow.bottom - rcWindow.top; } else { pOpt->cxWidth = rcWindow.right - rcWindow.left; } } } void CAppBarDlg::OnMove(int x, int y) { ASSERT (m_pAppBar); CDialog::OnMove(x, y); POPTIONS pOpt = m_pAppBar->GetAppbarData(); if (m_bMoving || pOpt->fAutoHide) { return; } m_pAppBar->Size(); } void CAppBarDlg::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: Popup menu here. CDialog::OnRButtonDown(nFlags, point); } void CAppBarDlg::OnTimer(UINT nIDEvent) { ASSERT (m_pAppBar); POPTIONS pOpt = m_pAppBar->GetAppbarData(); POINT pt; RECT rc; HWND hwndActive; switch (nIDEvent) { // The AUTOHIDE timer has fired. Check to see if the mouse is over our // window and if not hide the appbar. case IDT_AUTOHIDE: if ((pOpt->fAutoHide) && (!pOpt->fHiding)) { // Get the mouse position, the window position, and active // window GetCursorPos(&pt); GetWindowRect(&rc); hwndActive = (HWND) GetForegroundWindow(); // If the mouse is outside of our window, or we are not active, // or at least one window is active, or we are not the parent // of an active window, the hide the appbar window. if ((!PtInRect(&rc, pt)) && (hwndActive != m_hWnd) && (hwndActive != NULL) /*MOREWORK && (GetWindowOwner(hwndActive) != hwnd)*/) { KillTimer (nIDEvent); m_pAppBar->Hide (); } } break; // The period between the time the user has entered our window and the // time we should show the window has expired. case IDT_AUTOUNHIDE: // Kill the timer, we only need it to fire once. KillTimer (nIDEvent); GetWindowRect (&rc); if ((pOpt->fAutoHide) && (pOpt->fHiding)) { // Check to see if the cursor is still in the appbar. If so, // the unhide the window. GetCursorPos(&pt); if (PtInRect(&rc, pt)) { m_pAppBar->UnHide (); } } break; } CDialog::OnTimer(nIDEvent); } UINT CAppBarDlg::OnNcHitTest(CPoint point) { ASSERT (m_pAppBar); POPTIONS pOpt = m_pAppBar->GetAppbarData (); LRESULT lHitTest; // Take care of the autohide stuff if needed m_pAppBar->SetAutoUnhideTimer (); // Let DefWindowProc() tell us where the mouse is lHitTest = CWnd::OnNcHitTest(point); // We want to disable sizing in all directions except the inside edge. if ((pOpt->uSide == ABE_TOP) && (lHitTest == HTBOTTOM)) return HTBOTTOM; if ((pOpt->uSide == ABE_BOTTOM) && (lHitTest == HTTOP)) return HTTOP; if ((pOpt->uSide == ABE_LEFT) && (lHitTest == HTRIGHT)) return HTRIGHT; if ((pOpt->uSide == ABE_RIGHT) && (lHitTest == HTLEFT)) return HTLEFT; return HTCLIENT; } void CAppBarDlg::OnLButtonDown(UINT nFlags, CPoint point) { ASSERT (m_pAppBar); POPTIONS pOpt = m_pAppBar->GetAppbarData(); m_bMoving = TRUE; SetCapture(); CDialog::OnLButtonDown(nFlags, point); } void CAppBarDlg::OnMouseMove(UINT nFlags, CPoint point) { ASSERT (m_pAppBar); POINT ptCursor = {point.x, point.y}; LONG cxScreen, cyScreen; DWORD dx, dy; WORD horiz, vert; POPTIONS pOpt = m_pAppBar->GetAppbarData(); APPBARDATA abd; // If we're not currently in the middle of moving the appbar window, // there's nothing to do. if (!m_bMoving) { return; } // Convert the mouse position to screen coordinates ClientToScreen(&ptCursor); // Find out which edge of the screen we're closest to cxScreen = GetSystemMetrics(SM_CXSCREEN); cyScreen = GetSystemMetrics(SM_CYSCREEN); if (ptCursor.x < (cxScreen / 2)) { dx = ptCursor.x; horiz = ABE_LEFT; } else { dx = cxScreen - ptCursor.x; horiz = ABE_RIGHT; } if (ptCursor.y < (cyScreen / 2)) { dy = ptCursor.y; vert = ABE_TOP; } else { dy = cyScreen - ptCursor.y; vert = ABE_BOTTOM; } // Build a drag rectangle based on the edge of the screen that we're // closest to. if ((cxScreen * dy) > (cyScreen * dx)) { m_rcDrag.top = 0; m_rcDrag.bottom = cyScreen; if (horiz == ABE_LEFT) { m_rcDrag.left = 0; m_rcDrag.right = m_rcDrag.left + pOpt->cxWidth; pOpt->uSide = ABE_LEFT; } else { m_rcDrag.right = cxScreen; m_rcDrag.left = m_rcDrag.right - pOpt->cxWidth; pOpt->uSide = ABE_RIGHT; } } else { m_rcDrag.left = 0; m_rcDrag.right = cxScreen; if (vert == ABE_TOP) { m_rcDrag.top = 0; m_rcDrag.bottom = m_rcDrag.top + pOpt->cyHeight; pOpt->uSide = ABE_TOP; } else { m_rcDrag.bottom = cyScreen; m_rcDrag.top = m_rcDrag.bottom - pOpt->cyHeight; pOpt->uSide = ABE_BOTTOM; } } // Finally, make sure this is an OK position with the system and move // the window. abd.cbSize = sizeof(APPBARDATA); abd.hWnd = m_hWnd; m_pAppBar->QueryPos (&m_rcDrag); MoveWindow(m_rcDrag.left, m_rcDrag.top, m_rcDrag.right - m_rcDrag.left, m_rcDrag.bottom - m_rcDrag.top, TRUE); CDialog::OnMouseMove(nFlags, point); } void CAppBarDlg::OnLButtonUp(UINT nFlags, CPoint point) { ASSERT (m_pAppBar); APPBARDATA abd; POPTIONS pOpt = m_pAppBar->GetAppbarData(); if (!m_bMoving) { return; } // Update the global appbar rect used when we're autohiding. This is // sloppy but it works for now. It would be better to maintain two rects, // one for the hidden state and one for the unhidden state. m_pAppBar->m_rcAppBar = m_rcDrag; // Clean up the drag state info. ReleaseCapture(); // Calculate the hidden rect if we need to and then tell the system about // our new area. abd.cbSize = sizeof(APPBARDATA); abd.hWnd = m_hWnd; if (pOpt->fAutoHide) { switch (pOpt->uSide) { case ABE_TOP: m_rcDrag.bottom = m_rcDrag.top + 2; break; case ABE_BOTTOM: m_rcDrag.top = m_rcDrag.bottom - 2; break; case ABE_LEFT: m_rcDrag.right = m_rcDrag.left + 2; break; case ABE_RIGHT: m_rcDrag.left = m_rcDrag.right - 2; break; } } m_pAppBar->QuerySetPos(pOpt->uSide, &m_rcDrag, &abd, FALSE); m_bMoving = FALSE; CDialog::OnLButtonUp(nFlags, point); } /* * ShowMenu -- Show the menu for the corresponding button * * iResourceID - Resource of the menu * iBoldID - ID of the menu item that is the default (in bold) * - if -1 then there is no default * rect - Window position of the button who will contain this menu. */ BOOL CAppBarDlg::ShowMenu (const CRect& rect, int iResourceID, int iBoldID) { ASSERT (m_pAppBar); CMenu Menu; CMenu *pSubMenu; MENUITEMINFO mii; POPTIONS pOptions = m_pAppBar->GetAppbarData(); UINT uItem; TCHAR szMenu[64]; // Bring up the context menu if (Menu.LoadMenu(iResourceID)) { pSubMenu = Menu.GetSubMenu(0); // Set the default menu item mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_STATE; mii.fState = MFS_DEFAULT; if (iBoldID >= 0) { SetMenuItemInfo(pSubMenu->m_hMenu, iBoldID, FALSE, &mii); } mii.fMask = MIIM_TYPE | MIIM_STATE; (LPTSTR) mii.dwTypeData = szMenu; mii.cch = sizeof(szMenu); GetMenuItemInfo(pSubMenu->m_hMenu, uItem, FALSE, &mii); mii.fType |= MFT_RADIOCHECK; mii.fState = MFS_CHECKED; SetMenuItemInfo(pSubMenu->m_hMenu, uItem, FALSE, &mii); switch (pOptions->uSide) { case ABE_TOP: TrackPopupMenu (pSubMenu->m_hMenu, TPM_LEFTALIGN | TPM_TOPALIGN, rect.left, rect.bottom, 0, m_hWnd, NULL); break; case ABE_LEFT: TrackPopupMenu (pSubMenu->m_hMenu, TPM_LEFTALIGN | TPM_TOPALIGN, rect.left, rect.bottom, 0, m_hWnd, NULL); break; case ABE_RIGHT: TrackPopupMenu (pSubMenu->m_hMenu, TPM_RIGHTALIGN | TPM_TOPALIGN, rect.right, rect.bottom, 0, m_hWnd, NULL); break; case ABE_BOTTOM: TrackPopupMenu (pSubMenu->m_hMenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN, rect.left, rect.top, 0, m_hWnd, NULL); break; } return TRUE; } else { return FALSE; } }